#ifndef LISTA_H_
#define LISTA_H_

#include "Nodo.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <iostream>
#include <sstream>

using namespace std;

template<class T> class Lista{

private:

	Nodo<T>* primero;

public:

	Lista(){
		this->primero = NULL;
	}

	virtual ~Lista(){
		Nodo<T>* aux = primero;
		Nodo<T>* aux2;
		if(aux){
			aux2 = aux;
			while(aux->tieneSiguiente()){
				aux2 = aux->getSiguiente();
				delete aux;
				aux = aux2;
			}
			delete aux;
		}
	}

	bool estaVacia(){
		return(primero);
	}

	//agrega datos en orden decreciente segun ranking
	void agregarDato(T dato, long int ranking){
		Nodo<T>* nuevo = new Nodo<T>(dato,ranking);
		Nodo<T>* aux = primero;
		Nodo<T>* aux2 = primero;
		if(aux){
			if(aux->tieneSiguiente()){
				while((aux->tieneSiguiente())&&(aux->getRanking()>=nuevo->getRanking())){
					aux2 = aux;
					aux = aux->getSiguiente();
				}
				if(aux->getRanking()>=nuevo->getRanking()){aux->setSiguiente(nuevo);} //alta al final
				else{
					if(aux!=aux2){
						nuevo->setSiguiente(aux2->getSiguiente());
						aux2->setSiguiente(nuevo); //intercalo el nuevo
					}else{ //era el primero
						nuevo->setSiguiente(aux);
						primero = nuevo;
					}
				}
			}else{
				if(aux->getRanking()>=nuevo->getRanking()) { aux->setSiguiente(nuevo);} //alta al final
				else{
					nuevo->setSiguiente(aux);
					primero = nuevo;
				}
			}
		}
		else primero = nuevo;
	}

	//agrega datos, siempre al final de la lista
	void agregarDato(T dato){
		Nodo<T>* nuevo = new Nodo<T>(dato,0);
		Nodo<T>* aux = primero;
		Nodo<T>* aux2 = primero;
		while(aux){
			aux2 = aux;
			aux = aux->getSiguiente();
		}
		if(aux2) aux2->setSiguiente(nuevo);
		else primero = nuevo;
	}

	void removerDato(T dato){
		Nodo<T>* aux = primero;
		Nodo<T>* aux2;
		T buscado;
		while((aux->tieneSiguiente())&&(aux->getDato() != dato)){
			aux2 = aux;
			aux = aux->getSiguiente();
		}
		if(aux->getDato() == dato){
			if(aux2){
				aux2->setSiguiente(aux->getSiguiente());
				delete aux;
			}else{
				this->primero = aux->getSiguiente();
				delete aux;
			}
		}
	}

	Nodo<T>* buscarDato(T dato){
		Nodo<T>* aux = primero;
		while((aux->dato != dato)&&(aux->tieneSiguiente())){
			aux = aux->siguiente;
		}
		if(aux->dato == dato)return aux;
		return NULL;
	}

	Nodo<T>* getPrimero(){
		return primero;
	}
};

#endif
